package net.oschina.victor.service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import net.oschina.victor.entity.Resource;
import net.oschina.victor.entity.Role;
import net.oschina.victor.repsotory.RoleRepsotory;

@Service
public class RoleServiceImpl implements RoleService {
	@Autowired
	private RoleRepsotory roleRepsotory;
	@Autowired
	private ResourceService resourceService;

	@Override
	@Transactional
	public void deleteRole(Long roleId) {
		roleRepsotory.delete(roleId);
	}

	@Override
	public List<Role> findAll() {
		Specification<Role> spec = new Specification<Role>() {
			@Override
			public Predicate toPredicate(Root<Role> arg0, CriteriaQuery<?> arg1, CriteriaBuilder arg2) {
				return null;
			}
		};
		return roleRepsotory.findAll(spec);
	}

	@Override
	public Role findById(Long roleId) {
		return roleRepsotory.findOne(roleId);
	}

	@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
	@Override
	public Set<String> findPermissions(Set<Role> roles) {
		Set<Resource> resources = new HashSet<Resource>();
		for (Role role : roles) {
			if (role != null) {
				resources.addAll(role.getResources());
			}
		}
		return resourceService.findPermissions(resources);
	}

	@Override
	public Set<String> findRoles(Long... roleIds) {
		Set<String> roles = new HashSet<String>();
		for (Long roleId : roleIds) {
			Role role = findById(roleId);
			if (role != null) {
				roles.add(role.getRole());
			}
		}
		return roles;
	}

	@Override
	public Role saveRole(Role role) {
		return roleRepsotory.save(role);
	}

}
